from django.db.models import Model
from django.db import models
from collections import Iterable
from qiniu import Auth, put_file, etag, urlsafe_base64_encode, put_data
import uuid
from PIL import Image  #pip install pillow
import io


def model2dict(obj: Model, keys=None, exclude_keys=None):
    d = {}
    fields = obj.__class__._meta.fields
    fields_map = {f.name: f for f in fields}
    fields_keys = list(fields_map.keys())
    #
    output_keys = getattr(obj.__class__, 'get_output_fields', lambda : [])()
    secret_keys = getattr(obj.__class__, 'get_secret_fields', lambda : [])()
    ignore_keys = getattr(obj.__class__, 'get_ignore_fields', lambda : [])()
    if not keys:
        if output_keys:
            keys = output_keys
        else:
            keys = fields_keys
    if not exclude_keys:
        exclude_keys = []
    keys = list(set(keys) - set(exclude_keys+secret_keys+ignore_keys))
    for key in keys:
        if key in fields_keys:
            field = fields_map[key]
            if isinstance(field, models.ForeignKey) or isinstance(field, models.OneToOneField):
                val = getattr(obj, field.name + '_id')
                d[field.name] = {
                    'id': val if val else '',
                    'app_name': field.related_model._meta.app_label,
                    'model_name': field.related_model._meta.model_name,
                }
            elif isinstance(field, models.ManyToManyField):
                field_name = field.name
                d[field_name] = {
                    'ids': [e.id for e in getattr(obj, field.name).all()],
                    'app_name': field.related_model._meta.app_label,
                    'model_name': field.related_model._meta.model_name,
                }
            elif isinstance(field, models.BooleanField):
                d[field.name] = getattr(obj, field.name)
            else:
                val = getattr(obj, field.name)
                if callable(val):
                    d[field.name] = val()
                else:
                    d[field.name] = val.__str__() if val is not None else ''
        else:
            val = getattr(obj, key)
            if callable(val):
                d[key] = val()
            else:
                d[key] = val.__str__() if val is not None else ''
    return d


def field2info(field: models.Field):
    info = {
        'field_name': field.name,
        'field_label': field.verbose_name,
    }
    if field.choices:
        info['field_choices'] = field.choices
    if isinstance(field, models.ForeignKey) or isinstance(field, models.OneToOneField):
        info['field_name'] += '_id'
        info['app_name'] = field.related_model._meta.app_label
        info['model_name'] = field.related_model._meta.model_name

    return info

def upload(img):
    _img = img.read()
    size = len(_img) / (1024 * 1024)#上传图片的大小 M单位
    print(size)
    image = Image.open(io.BytesIO(_img))
    key = str(uuid.uuid1()).replace('-', '') + '.' + image.format
    access_key = 'xvNJWAUqvla_QpNs5ZPEO6ZaEbNV9e__Tqjx2Nys'
    secret_key = 'yQMv_6jVk5mUFJ1joNfSY2fI5h7xhoEIOti0dvot'
    q = Auth(access_key, secret_key)
    bucket_name = 'superlinks'
    token = q.upload_token(bucket_name, key, 3600, )
    name = 'upfile.{0}'.format(image.format) #获取图片后缀（图片格式）
    if size > 1:
        x, y = image.size
        im = image.resize((int(x / 1.73), int(y / 1.73)), Image.ANTIALIAS) #等比例压缩 1.73 倍
        print('压缩')
    else:
        print('不压缩')
        im = image
    # im = image
    im.save('./media/' + name) #在根目录有个media文件
    path = './media/' + name
    # up = im.read()
    ret, info = put_file(token, key, path)
    url = 'http://oq0zkmcec.bkt.clouddn.com/{}'.format(key)
    return url
